import os
import random
import shutil
import time
import zipfile

import requests
from bs4 import BeautifulSoup as bs
import re
import json
import os
import glob
import subprocess

class myZipFile():
    def zipSingleFile(self,filename,zip_filename):
        zf = zipfile.ZipFile(zip_filename,"w",  zipfile.ZIP_DEFLATED)
        #写入文件，可以一次性将多个文件压缩，打包
        filename1=filename.split('/')[-1]
        zf.write(filename,arcname=filename1, compress_type=None)#将指定文件写入ZIP文档中
        # 关闭文件
        zf.close()
        #参数filename:需要写入文件的路径

        #参数arcname:文件写入ZIP文档后保存的文件名

        #参数compress_type:压缩方法(ZIP_STORED或ZIP_DEFAULED)

    def noSourcePathzip(self,my_zip,my_dir):

         with zipfile.ZipFile(my_zip) as zip_file:
             for member in zip_file.namelist():
                 filename = os.path.basename(member)
                 # skip directories
                 if not filename:
                     continue

                 # copy file (taken from zipfile's extract)
                 source = zip_file.open(member)
                 target = open(os.path.join(my_dir, filename), "wb")
                 with source, target:
                     shutil.copyfileobj(source, target)

class SpiderQingyunian():
    def __init__(self):

        self.base_url_list = ['https://v.cdnlz21.com/20240516/332_8de22974/2000k/hls/f0b8c355de5000',  # 第一集
                              'https://v.cdnlz21.com/20240516/333_4ff93945/2000k/hls/e7b4dec55c1000',
                              'https://v.cdnlz21.com/20240516/330_5bffc4cc/2000k/hls/2fbd2870f19000',
                              'https://v.cdnlz21.com/20240516/331_42d2a497/2000k/hls/f1f22823e5c000', #4
                              'https://v.cdnlz21.com/20240516/328_65ba038f/2000k/hls/d072ccc5c85000',
                              'https://v.cdnlz12.com/20240517/14371_093907ff/2000k/hls/4ff403a7dd6000',#6 'https://v.cdnlz12.com/20240517/14371_093907ff/2000k/hls/4ff403a7dd6000003.ts'
                              'https://v.cdnlz12.com/20240517/14370_946155cb/2000k/hls/b856a36498f000',
                              'https://v.cdnlz12.com/20240518/14410_5f51d516/2000k/hls/41ab1d5fe89000',#8
                              'https://v.cdnlz12.com/20240519/14439_5e24ec88/2000k/hls/45c76f41c2a000',
                              'https://v.cdnlz12.com/20240520/14474_30e8bcda/2000k/hls/678ad20d611000',#10
                              'https://v.cdnlz12.com/20240520/14473_e5437b4b/2000k/hls/834c43bcc16000',
                              'https://v.cdnlz12.com/20240521/14536_0f45d964/2000k/hls/7181f5f54f7000',#12
                              'https://v.cdnlz12.com/20240521/14535_685c11e5/2000k/hls/37b589aeebe000',
                              'https://v.cdnlz12.com/20240522/14551_11bfaca0/2000k/hls/2da6ea8f30a000',#14
                              'https://v.cdnlz3.com/20240524/23204_00823d13/2000k/hls/a6b803ef2f2000',
                              'https://v.cdnlz3.com/20240524/23203_7ce814e9/2000k/hls/3822bb86c96000', #16
                              'https://v.cdnlz3.com/20240524/23202_a8a9faa7/2000k/hls/ae4f9b99f62000',
                              'https://v.cdnlz3.com/20240524/23212_e8eac469/2000k/hls/7916c0f3f02000',#18
                              'https://v.cdnlz3.com/20240524/23211_e033d585/2000k/hls/da63c040bcf000',
                              'https://v.cdnlz3.com/20240528/23388_541ace81/2000k/hls/6b473ff2956000',
                              'https://v.cdnlz3.com/20240525/23250_d591a49e/2000k/hls/b94e74166ca000',#21
                              'https://v.cdnlz3.com/20240526/23292_050ff255/2000k/hls/9c2253e0a6e000',
                              'https://v.cdnlz3.com/20240526/23295_bdd44ced/2000k/hls/134ee9591fb000',
                              'https://v.cdnlz3.com/20240527/23347_6281a322/2000k/hls/dd34b8306bf000',#24
                              'https://v.cdnlz12.com/20240527/14701_96169b02/2000k/hls/d41758885f8000',
                              'https://v.cdnlz3.com/20240528/23397_741360c4/2000k/hls/bae70626ee8000',#26
                              'https://v.cdnlz12.com/20240528/14702_8387d908/2000k/hls/3d9e7057bb9000',#27
                              'https://v.cdnlz3.com/20240529/23464_47a3b801/2000k/hls/1f187594edd000',#28
                              'https://v.cdnlz12.com/20240529/14704_69364210/2000k/hls/5a6c2ffe73e000',
                              'https://v.cdnlz12.com/20240530/14722_fb06c6cb/2000k/hls/68d661aa6d3000',#30
                              'https://v.cdnlz12.com/20240530/14721_54933df7/2000k/hls/a772a1e9c4c000',
                              'https://v.cdnlz12.com/20240530/14733_96471e80/2000k/hls/db433eae9ae000',#32
                              'https://v.cdnlz12.com/20240531/14738_726cfa13/2000k/hls/bc196162c92000',
                              'https://v.cdnlz3.com/20240530/23517_b83e3e8f/2000k/hls/9787088df41000',
                              'https://v.cdnlz3.com/20240530/23515_ddf9628c/2000k/hls/8341d6336c3000',#35
                              'https://v.cdnlz3.com/20240530/23516_3e4d5a57/2000k/hls/786dc04eeb5000' #36




                              ]

        self.save_dir=r"C:\Users\Administrator\Desktop\Qingyunian"
        self.base_url = 'https://v.cdnlz21.com/20240516/332_8de22974/2000k/hls/f0b8c355de5000'
        self.headers_list= [
    {
        'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 8.0.0; SM-G955U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 10; SM-G981B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.162 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (iPad; CPU OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/87.0.4280.77 Mobile/15E148 Safari/604.1'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.109 Safari/537.36 CrKey/1.54.248666'
    }, {
        'user-agent': 'Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.188 Safari/537.36 CrKey/1.54.250320'
    }, {
        'user-agent': 'Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+'
    }, {
        'user-agent': 'Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.80 Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/102.0.0.0 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 6.0.1; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)'
    }, {
        'user-agent': 'Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.158 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 11; Pixel 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.181 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36'
    }, {
        'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1'
    }, {
        'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'
    }, {
        'user-agent': 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1'
    }, {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0'
    }
]
        self.proxies = {
            'http': '127.0.0.1:1212',
            'https': '127.0.0.1:1212'
        }

        self.ts_data=None
        self.zip=myZipFile()
        self.ts_range=700
    def get_m3u8url_list(self, num=0):

        if (num < len(self.base_url_list)):
            base_url = self.base_url_list[num]
            url_list = []
            for i in range(self.ts_range):
                url_list.append(base_url + '{}.ts'.format(str(i).zfill(3)))
            print(url_list)
            return url_list
        else:
            print("没有这一集")
            return False

    def get_m3u8url_list1(self, num=0):

        if (num < len(self.base_url_list)):
            base_url = self.base_url_list[num]
            url_list = []
            for i in range(2):
                url_list.append(base_url + '{}.ts'.format(str(i+1000).zfill(3)))
            print(url_list)
            return url_list
        else:
            print("没有这一集")
            return False
    def download_m3u8(self, url_list,num=0):

        for i in range(len(url_list)):
            # headers=random.choice(self.headers_list)
            # data = requests.get(url_list[i],headers=headers).content#每次请求随机变换请求头
            # time.sleep(random.randrange(1,5))#防止请求过频繁
            res=self.connectUrl(url_list[i])
            if(res==2):
                print(f'无法下载第{i}个{url_list[i]}文件')
                return 2

            # 请求数据
            path1=os.path.join(self.save_dir,f'vedio_{num+1}')
            if(os.path.exists(path1) and os.path.isdir(path1)):
                pass
            else:
                os.mkdir(path1)
            n=str(i).zfill(4)
            filename=f'{path1}/vedio{n}' + '.ts'
            with open(filename, mode='wb') as f:
                f.write(self.ts_data)
                print(f'正在保存数据{i}')

            self.drop_empt_file(filename)#如果文件大小小于一定值判断为空文件，删除
    def connectUrl(self,url,times=0):
        if(times>20):
            return 2
        try:
            headers = random.choice(self.headers_list)#每次请求随机变换请求头
            self.ts_data = requests.get(url, headers=headers).content
            time.sleep(random.randrange(1, 5))  # 防止请求过频繁
            return 0
        except:
            time.sleep(random.randrange(1, 5))  # 防止请求过频繁
            times+=1
            self.connectUrl(url,times=times)




    def drop_empt_file(self,filename,limit=200):

        size=os.path.getsize(filename)
        if(size<limit):
            print(f'remove {filename}')
            os.remove(filename)



    def get_mp4_ts(self,ts_path, mp4_path):
        ts_list = glob.glob(os.path.join(ts_path, "*.ts"))
        index = 0
        for i in ts_list:
            subprocess.run(['ffmpeg', '-i', i, i.replace(ts_path.split('/')[-1], mp4_path).replace(".ts", ".mp4")])
            print(i, index)
            index += 1

    def merge(self,filenames, dirname, video='video.mp4'):
        # 先用一个文件保存所有的文件路径(格式：file '\*\*\*.ts')
        if(os.path.isdir(dirname)):
            pass
        else:
            os.mkdir(dirname)

        path = os.path.join(dirname, 'path.txt')
        with open(path, 'w+') as f:
            for filename in filenames:
                f.write("file '%s' \n" % os.path.join(filename))

        os.chdir(dirname)
        os.system('ffmpeg -f concat -safe 0 -y -i %s -c copy -strict -2 %s' % (path, os.path.join(dirname, video)))

    def getFilenames(self,num=0):
        dir=os.path.join(self.save_dir,f'vedio_{num+1}')
        if(os.path.isdir(dir)):
           namelist=os.listdir(dir)
           newlist=[]
           for name in namelist:
               name=os.path.join(dir,name)
               # print(name)
               newlist.append(name)
           return newlist
        else:
            return False





    def download_num(self, num=0):
        print("第{}集下载......".format(num + 1))
        list1 = self.get_m3u8url_list(num=num)
        if (list1 == False):
            return
        else:
            self.download_m3u8(list1,num=num)

    def getTS2MP4(self,num=0):
        self.download_num(num=num)
        list=self.getFilenames(num=num)
        dirname=os.path.join(self.save_dir,f'output/video{num+1}')
        self.merge(filenames=list,dirname=dirname,video=f'video{num+1}.mp4')
        self.zip.zipSingleFile(filename=os.path.join(dirname,f'video{num+1}.mp4'),zip_filename=os.path.join(dirname,f'video{num+1}.zip'))
        # self.zip.noSourcePathzip(my_zip=os.path.join(dirname,f'video{num+1}.zip'),my_dir=dirname)
    def getMP4_batch(self):
        for i in range(len(self.base_url_list)):
            if(i>7):
                self.getTS2MP4(num=i)

if __name__ == '__main__':
    spider = SpiderQingyunian()
    # spider.download_num(num=3)
    #spider.download_m3u8(url_list=list)
    # list=spider.get_m3u8url_list(num=0)
    # spider.download_m3u8(num=0,url_list=list)
    # spider.get_mp4_ts(ts_path=r"C:\Users\Administrator\Desktop\Qingyunian\vedio_4",mp4_path=r"C:\Users\Administrator\Desktop\Qingyunian\output")
    #获取文件夹下所有ts文件名
    # spider.download_num(num=5)
    # list=spider.getFilenames(num=5)
    # print(list)
    # print(len(list))
    # spider.merge(filenames=list,dirname=r"C:\Users\Administrator\Desktop\Qingyunian\output",video="video_3.mp4")
    # str='copy /b {}\*.ts {}'.format(r'C:\Users\Administrator\Desktop\Qingyunian\vedio_4',r'C:\Users\Administrator\Desktop\Qingyunian\vedio_4.mp4')
    spider.getMP4_batch()